/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.workflow.service.push;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.bpm.core.model.config.ProcessRemindTemplateTypeEnum;
import com.je.bpm.core.model.config.ProcessRemindTypeEnum;
import com.je.bpm.core.model.config.process.ProcessRemindTemplate;
import com.je.bpm.engine.ActivitiException;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.message.vo.Notice;
import com.je.common.base.service.MetaRbacService;
import com.je.common.base.util.SecurityUserHolder;
import com.je.workflow.service.push.pojo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class PushServiceImpl implements PushService {
    @Autowired
    private MetaRbacService metaService;
    @Autowired
    public RedisTemplate redisTemplate;
    public static final String delayQueueName = "delayQueue";

    private static final String pushType = "WF";

    @Override
    public void pushMsg(String userId, String funcCode, String modelName, String submitType, String comment, String pkValue) {
        String userName = SecurityUserHolder.getCurrentAccountRealUserName();
        new Thread(() -> {
            Notice notice = new Notice();
            notice.setTitle("流程提醒");
            String content = String.format("由【%s】在【%s】给您提交了【%s】任务, 执行操作：【%s】,执行意见：【%s】",
                    userName, DateUtil.now(), modelName, submitType, comment);
            if (Strings.isNullOrEmpty(comment)) {
                content = String.format("由【%s】在【%s】给您提交了【%s】任务, 执行操作：【%s】",
                        userName, DateUtil.now(), modelName, submitType);
            }
            notice.setContent(content);
            notice.setPlayAudio(true);
            //右下角通知
            RedisDelayQueue redisDelayQueue = new RedisDelayQueue(redisTemplate, delayQueueName);
            redisDelayQueue.setDelayQueue(new CommonMessageVo(userId, funcCode, pushType, notice, pkValue, new HashMap<>()),
                    PushMessageTypeEnum.SOCKET_PUSH_OPEN_FUNC_FORM_MSG.getName(), userId + "_流程提醒_" + comment
                    , System.currentTimeMillis());
        }).start();
    }

    @Override
    public void pushRefresh(String userId) {
        try {
            JSONObject content = new JSONObject();
            content.put("pushType", "load");
//            PushSystemMessage pushSystemMessage = new PushSystemMessage(pushType, content.toJSONString());
//            pushSystemMessage.setTargetUserIds(Lists.newArrayList(userId));
//            pushSystemMessage.setSourceUserId("系统");
            RedisDelayQueue redisDelayQueue = new RedisDelayQueue(redisTemplate, delayQueueName);
            CommonMessageVo commonMessageVo = new CommonMessageVo();
            commonMessageVo.setPushType(pushType);
            commonMessageVo.setContent(content.toJSONString());
            commonMessageVo.setToUserId(userId);
            commonMessageVo.setSourceUserId("系统");
            redisDelayQueue.setDelayQueue(commonMessageVo, PushMessageTypeEnum.SOCKET_PUSH_SYSTEM_MESSAGE.getName()
                    , userId + "_" + content.toJSONString(), System.currentTimeMillis());
//            socketPushMessageRpcService.sendMessage(pushSystemMessage);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ActivitiException("消息推送异常！");
        }
    }

    @Override
    public void pushDiffTypeMsg(String userId, List<ProcessRemindTypeEnum> processRemindTypeEnumList,
                                List<ProcessRemindTemplate> processRemindTemplates, MessageDTO messageDTO) {
        if (processRemindTypeEnumList.isEmpty()) {
            return;
        }
        String submitType = messageDTO.getSubmitType();
        String modelName = messageDTO.getModelName();
        String comment = messageDTO.getComment();
        String pkValue = messageDTO.getPkValue();
        String funcCode = messageDTO.getFuncCode();
        List<DynaBean> userDynaBeanList = metaService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_USER")
                .eq("JE_RBAC_USER_ID", userId).eq("USER_EMPLOYEE_STATUS", "1"));
        if (userDynaBeanList.isEmpty()) {
            return;
        }
        String userPhone = userDynaBeanList.get(0).getStr("USER_PHONE");
        String userMail = userDynaBeanList.get(0).getStr("USER_MAIL");
        String toUserName = userDynaBeanList.get(0).getStr("USER_NAME");
        //当前登陆用户名
        String userName = messageDTO.getSubmitUserName();
        //消息提醒标题模板
        String title = "";
        for (ProcessRemindTemplate processRemindTemplate : processRemindTemplates) {
            if (!ProcessRemindTemplateTypeEnum.TITLE.getType().equals(processRemindTemplate.getType().getType())) {
                continue;
            }
            title = processRemindTemplate.getTemplate();
        }
        title = WorkFlowVariable.formatVariable(title, messageDTO.getVariables());
        //消息提醒第三方模板
        String thirdParty = "";
        for (ProcessRemindTemplate processRemindTemplate : processRemindTemplates) {
            if (!ProcessRemindTemplateTypeEnum.THIRDPARTY.getType().equals(processRemindTemplate.getType().getType())) {
                continue;
            }
            thirdParty = processRemindTemplate.getTemplate();
        }
        String thirdPartyContent = "";
        if (Strings.isNullOrEmpty(thirdParty)) {
            thirdPartyContent = "";
        } else {
            thirdParty = WorkFlowVariable.formatVariable(thirdParty, messageDTO.getVariables());
            thirdPartyContent = CommonSystemVariable.formatVariable(thirdParty);
        }
        //消息推送类型（按不同类型推送）
        for (ProcessRemindTypeEnum processRemindTypeEnum : processRemindTypeEnumList) {
            CommonMessageVo commonMessageVo = null;
            if (ProcessRemindTypeEnum.WEB.name().equals(processRemindTypeEnum.name())) {
                Notice notice = new Notice();
                notice.setPlayAudio(true);
                commonMessageVo = new CommonMessageVo(userId, funcCode, pushType, notice, pkValue, messageDTO.getVariables());
            } else if (ProcessRemindTypeEnum.NOTE.name().equals(processRemindTypeEnum.name())) {
                commonMessageVo = new NoteMessageVo(userId, userPhone, toUserName, messageDTO.getSubmitUserName(),
                        messageDTO.getSubmitUserId());
                commonMessageVo.setVariables(messageDTO.getVariables());
            } else if (ProcessRemindTypeEnum.EMAIL.name().equals(processRemindTypeEnum.name())) {
                commonMessageVo = new EmailMessageVo(userMail, "HTML");
                commonMessageVo.setVariables(messageDTO.getVariables());
            }
            PushMessageFactory.createMessage(processRemindTypeEnum).execute(processRemindTemplates,
                    title, userName, modelName, submitType, comment, userId,
                    commonMessageVo, thirdPartyContent, "");
        }
    }

    @Override
    public void pushUrgeMsg(String userId, MessageDTO messageDTO, List<String> list, String content, String reminderName) {
        String submitType = messageDTO.getSubmitType();
        String modelName = messageDTO.getModelName();
        String comment = messageDTO.getComment();
        String pkValue = messageDTO.getPkValue();
        String funcCode = messageDTO.getFuncCode();
        List<DynaBean> userDynaBeanList = metaService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_USER")
                .eq("JE_RBAC_USER_ID", userId).eq("USER_EMPLOYEE_STATUS", "1"));
        if (userDynaBeanList.isEmpty()) {
            return;
        }
        String userPhone = userDynaBeanList.get(0).getStr("USER_PHONE");
        String userMail = userDynaBeanList.get(0).getStr("USER_MAIL");
        String toUserName = userDynaBeanList.get(0).getStr("USER_NAME");
        //当前登陆用户名
        String userName = messageDTO.getSubmitUserName();
        String title = String.format("流程%s通知", reminderName);
        //消息推送类型（按不同类型推送）
        for (String type : list) {
            ProcessRemindTypeEnum processRemindTypeEnum = ProcessRemindTypeEnum.getType(type);
            CommonMessageVo commonMessageVo = null;
            if (ProcessRemindTypeEnum.WEB.name().equals(processRemindTypeEnum.name())) {
                Notice notice = new Notice();
                notice.setPlayAudio(true);
                commonMessageVo = new CommonMessageVo(userId, funcCode, pushType, notice, pkValue, messageDTO.getVariables());
            } else if (ProcessRemindTypeEnum.NOTE.name().equals(processRemindTypeEnum.name())) {
                commonMessageVo = new NoteMessageVo(userId, userPhone, toUserName, messageDTO.getSubmitUserName(),
                        messageDTO.getSubmitUserId());
                commonMessageVo.setVariables(messageDTO.getVariables());
            } else if (ProcessRemindTypeEnum.EMAIL.name().equals(processRemindTypeEnum.name())) {
                commonMessageVo = new EmailMessageVo(userMail, "HTML");
                commonMessageVo.setVariables(messageDTO.getVariables());
            }
            PushMessageFactory.createMessage(processRemindTypeEnum).execute(new ArrayList<>(),
                    title, userName, modelName, submitType, comment, userId,
                    commonMessageVo, "", content);
        }
    }

    @Override
    public void pushApprovalNoticeMsg(String userId, String funcCode, String modelName, String title, String comment, String pkValue) {
        new Thread(() -> {
            Notice notice = new Notice();
            notice.setTitle("流程告知提醒");
            notice.setContent(comment);
            notice.setPlayAudio(true);
            //右下角通知
            RedisDelayQueue redisDelayQueue = new RedisDelayQueue(redisTemplate, delayQueueName);
            redisDelayQueue.setDelayQueue(new CommonMessageVo(userId, funcCode, pushType, notice, pkValue, new HashMap<>()),
                    PushMessageTypeEnum.SOCKET_PUSH_OPEN_FUNC_FORM_MSG.getName(), userId + "_流程告知提醒_" + comment
                    , System.currentTimeMillis());
        }).start();
    }
}
